home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 2003-07-17 | 46.5 KB | 1,915 lines
// Copyright (C) 1997-2002 Alias|Wavefront, // a division of Silicon Graphics Limited. // // The information in this file is provided for the exclusive use of the // licensees of Alias|Wavefront. Such users have the right to use, modify, // and incorporate this code into other products for purposes authorized // by the Alias|Wavefront license agreement, without fee. // // ALIAS|WAVEFRONT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, // INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO // EVENT SHALL ALIAS|WAVEFRONT BE LIABLE FOR ANY SPECIAL, INDIRECT OR // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, // DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. // includeEffectsGlobals(); global string $gSpriteWizardParticle; proc int swFrameRange() // // Description: // Return the selected image frame range // { int $startFrame = `intFieldGrp -q -value1 swFileRangeInt`; int $endFrame = `intFieldGrp -q -value2 swFileRangeInt`; return ($endFrame-$startFrame); } proc int newImageFileName(string $imageFile) // // Description: // Return whether the file name is new or not // { global string $gSpriteWizardParticle; string $fileTexture = particleSpriteFileTexture( $gSpriteWizardParticle ); if ("" != $fileTexture) { string $file = `getAttr ($fileTexture+".fileTextureName")`; return ($file != $imageFile); } return 0; } proc int existingSpriteAnimation() // // Description: // Return the current sprite animation attribute value // { global string $gSpriteWizardParticle; if("" != $gSpriteWizardParticle && `attributeQuery -exists -node $gSpriteWizardParticle SpriteAnimation` ) { int $animVal = `getAttr ($gSpriteWizardParticle+".SpriteAnimation")`; return $animVal; } return 0; } proc createHelpButtons(string $parent) // // Description: // Create buttons (one for each frame) that also switch between // the tabs. // // Arguments: // The parent argument is assumed to be a formLayout. // { setParent $parent; string $frame1 = `button -label "Close" -ann "Close this window" -command "deleteUI WizardHelpWindow"`; string $frame2 = `button -label "Read Manual" -ann "Open web window to the manual to sprites" -command ("//showHelp")`; // Marker needs to be added formLayout -edit -attachForm $frame1 "top" 5 -attachForm $frame1 "left" 5 -attachForm $frame1 "bottom" 5 -attachPosition $frame1 "right" 2 50 -attachForm $frame2 "top" 5 -attachPosition $frame2 "left" 2 50 -attachPosition $frame2 "right" 2 100 -attachForm $frame2 "bottom" 5 $parent; } proc wizardHelpWindow(string $helpTitle, string $helpText[]) { // If the window already exists then just show it and return. // if (`window -exists WizardHelpWindow`) { deleteUI -window WizardHelpWindow; } // Otherwise, build the window. // window -title ("Sprite Wizard Help") -iconName "Sprite Wizard" -width 500 -height 200 -sizeable true WizardHelpWindow; string $form = `formLayout SpriteWizardForm`; string $textArea = `columnLayout`; text -align "center" -l $helpTitle; separator -w 200 -h 5 -style "in"; string $txt; for ($txt in $helpText) { text -l $txt; } setParent ..; string $buttons = `formLayout`; setParent ..; createHelpButtons($buttons); formLayout -edit -attachForm $textArea "top" 0 -attachForm $textArea "left" 0 -attachControl $textArea "bottom" 0 $buttons -attachForm $textArea "right" 0 -attachNone $buttons "top" -attachForm $buttons "left" 0 -attachForm $buttons "bottom" 0 -attachForm $buttons "right" 0 $form; showWindow WizardHelpWindow; } proc string[] selectedParticleObjects() // // Description: // Return the list of selected particle objects. { string $selList[] = `ls -sl`; int $particleCount; string $list[]; int $i; for ($i = size($selList)-1; $i >= 0; $i--) { if (`particleExists $selList[$i]`) { $list[ $particleCount ] = $selList[$i]; $particleCount++; } } return $list; } global proc int particleIsSelected() // // Description: // Return true if some particle object is selected, false otherwise. { string $selList[] = selectedParticleObjects(); return (size($selList) > 0); } global proc spriteWizard( string $object, string $image ) // // Description: // Determine the exact sequence of images to be used (sorting out issues of // suffixes and suff formatting), then launch the main wizard window. { // Get the particle shape. // string $shape = getShapeFromObject( $object, 0, 0 ); // Build and launch the wizard window // wizardWindow( $shape, $image ); } global proc spriteWizardVisor( string $image ) // // Description: // This is the front end to invoke the wizard from Visor. // Currently it just passes the file name to the main wizard. { // Get list of selected particle objects. // string $objects[] = selectedParticleObjects(); if (size($objects) == 0) { error("Please choose a particle object to which to apply sprites"); return; } else if (size($objects) > 1) { error("Please choose just one particle object"); return; } spriteWizard( $objects[0], $image ); } global proc spriteWizardMenu() // // Description: // This is the front end for the wizard from the Particles menu. // It invokes a file dialog to get an image name, and passes // that to the main wizard. // { // We need a unique selected particle object to proceed. // string $objects[] = selectedParticleObjects(); if (size($objects) == 0) { error("Please choose a particle object to which to apply sprites"); return; } else if (size($objects) > 1) { error("Please choose just one particle object"); return; } spriteWizard( $objects[0], "" ); } proc doApplySprites() // // Description: // This is the routine which finishes the wizard's action by actually applying the sprites. // It reads the input values from the controls and calls the applySpriteWizard script // to make the nodes and generate the expressions. { // User has hit "apply." Apply the sprites, we're done. // int $startFrame = `intFieldGrp -q -value1 swFileRangeInt`; int $endFrame = `intFieldGrp -q -value2 swFileRangeInt`; string $shape = `textField -q -text swGlobalParticleShape`; string $image = `textFieldButtonGrp -q -fileName swFileSelectionGroup`; int $animation = 0; int $selection = 0; int $cycle = 0; float $cycleLength = 100; int $invert = 0; // // Get the animation option. // string $animationOption = `radioCollection -q -select swAnimationOptionCollection`; if( $animationOption == "swSingleImageButton" ) { $animation = 0; } else if( $animationOption == "swCycleButton" ) { $animation = 1; } else { $animation = existingSpriteAnimation(); } // // Get the image selection option. // string $imageSelectionOption = `radioCollection -q -select swImageSelectionOptionCollection`; if( $imageSelectionOption == "swFirstImageButton" ) { $selection = 0; } else if( $imageSelectionOption == "swParticleIdButton" ) { $selection = 1; } else if( $imageSelectionOption == "swRandomButton" ) { $selection = 2; } else if( $imageSelectionOption == "swSpriteNumPPButton" ) { $selection = 3; } else if( $imageSelectionOption == "swInitRampButton" ) { $selection = 4; } else { warning("Invalid image selection option selected."); } // // Get the cycle option. // string $cycleOption = `radioCollection -q -select swCycleOptionCollection`; if( $cycleOption == "swLinearUpButton" ) { $cycle = 0; } else if( $cycleOption == "swSmoothUpButton" ) { $cycle = 1; } else if( $cycleOption == "swLinearUpDownButton" ) { $cycle = 2; } else if( $cycleOption == "swSmoothUpDownButton" ) { $cycle = 3; } else if ( $cycleOption == "swSpriteCustomButton" ) { $cycle = 4; } else if ( $cycleOption == "swRampButton" ) { $cycle = 5; } // // Get cycle length. // if( `checkBox -q -value swCycleOnceCheckbox` ) { $cycleLength = 0; } else { $cycleLength = `floatSliderGrp -q -value swCycleLengthValue`; } // // Get the invert value. // if( $animation == 0 ) { if( `radioCollection -q -select swCycleOptionCollection` == "swRampButton" ) { $invert = `checkBox -q -value swInvertRampCheckbox`; } } else { if( `radioCollection -q -select swCycleOptionCollection` == "swRampButton" ) { $invert = `checkBox -q -value swInvertRampCheckbox`; } else { $invert = `checkBox -q -value swInvertCycleCheckbox`; } } // Invoke applySpriteWizard to build the sprites. // applySpriteWizard( $shape, $image, $startFrame, $endFrame, $animation, $selection, $cycle, $cycleLength, $invert ); // Take down the sprite wizard window // deleteUI -window WizardExampleWindow; } global proc wizardExampleWindowSelectFileSelection() { textField -e -text "file" swGlobalCurrentFrame; tabLayout -edit -selectTab swFileSelectionLayout WizardExampleWindowTabs; string $selectedFile = `textFieldButtonGrp -q -fileName swFileSelectionGroup`; if( ( $selectedFile == "" ) || ( `filetest -r $selectedFile` == 0 ) ) { button -e -enable false applyContinueButton; } else { button -e -enable true applyContinueButton; } button -e -label "Continue" applyContinueButton; button -e -enable false backButton; } global proc wizardExampleWindowSelectAnimation() // // Description: // Invoked when Frame 1 button is selected. // // Make Frame 1 active. // { textField -e -text "animation" swGlobalCurrentFrame; tabLayout -edit -selectTab swAnimationOptionsLayout WizardExampleWindowTabs; updateAnimationApplyButton(); button -e -enable true backButton; } global proc wizardExampleWindowSelectImageSelection() // // Description: // Invoked when Frame 2 button is selected. // // Make Frame 2 active. // { textField -e -text "imageSelection" swGlobalCurrentFrame; tabLayout -edit -selectTab swImageSelectionLayout WizardExampleWindowTabs; button -e -label "Continue" applyContinueButton; button -e -enable true backButton; } global proc wizardExampleWindowSelectCycle() // // Description: // Invoked when Frame 3 button is selected. // // Make Frame 3 active. // { textField -e -text "cycle" swGlobalCurrentFrame; tabLayout -edit -selectTab swCycleOptionsLayout WizardExampleWindowTabs; button -e -label "Continue" applyContinueButton; button -e -enable true backButton; } global proc wizardExampleWindowSelectSummary() // // Description: // Invoked when Frame 3 button is selected. // // Make Frame 3 active. // { // // Generate the summary string. // int $startFrame = `intFieldGrp -q -value1 swFileRangeInt`; int $endFrame = `intFieldGrp -q -value2 swFileRangeInt`; string $shape = `textField -q -text swGlobalParticleShape`; string $image = `textFieldButtonGrp -q -fileName swFileSelectionGroup`; int $animation = 0; int $selection = 0; int $cycle = 0; float $cycleLength = 100; int $invert = 0; // // Get the animation option. // string $animationOption = `radioCollection -q -select swAnimationOptionCollection`; if( $animationOption == "swSingleImageButton" ) { $animation = 0; } else if( $animationOption == "swCycleButton" ) { $animation = 1; } else { warning("Invalid sprite animation option selected."); } // // Get the image selection option. // string $imageSelectionOption = `radioCollection -q -select swImageSelectionOptionCollection`; if( $imageSelectionOption == "swFirstImageButton" ) { $selection = 0; } else if( $imageSelectionOption == "swParticleIdButton" ) { $selection = 1; } else if( $imageSelectionOption == "swRandomButton" ) { $selection = 2; } else if( $imageSelectionOption == "swSpriteNumPPButton" ) { $selection = 3; } else if( $imageSelectionOption == "swInitRampButton" ) { $selection = 4; } else { warning("Invalid image selection option selected."); } // // Get the cycle option. // string $cycleOption = `radioCollection -q -select swCycleOptionCollection`; if( $cycleOption == "swLinearUpButton" ) { $cycle = 0; } else if( $cycleOption == "swSmoothUpButton" ) { $cycle = 1; } else if( $cycleOption == "swLinearUpDownButton" ) { $cycle = 2; } else if( $cycleOption == "swSmoothUpDownButton" ) { $cycle = 3; } else if( $cycleOption == "swSpriteCustomButton" ) { $cycle = 4; } else if( $cycleOption == "swRampButton" ) { $cycle = 5; } // // Get cycle length. // if( `checkBox -q -value swCycleOnceCheckbox` ) { $cycleLength = 0; } else { $cycleLength = `floatSliderGrp -q -value swCycleLengthValue`; } // // Get the invert value. // if( $animation == 0 ) { if( `radioCollection -q -select swImageSelectionOptionCollection` == "swRampButton" ) { $invert = `checkBox -q -value swInvertRampCheckbox`; } } else { if( `radioCollection -q -select swImageSelectionOptionCollection` == "swRampButton" ) { $invert = `checkBox -q -value swInvertRampCheckbox`; } else { $invert = `checkBox -q -value swInvertCycleCheckbox`; } } string $summary = ""; $summary += "Particle object: "+$shape+"\n"; $summary += "Sprite Image:\n"; $summary += " "+$image+"\n"; $summary += " Frames: " +$startFrame+" - "+$endFrame+"\n"; if( $animation == 0 ) { $summary += "No Animation:\n"; switch( $selection ) { case 0: $summary += " All particles use the first image in the sequence\n"; break; case 1: $summary += " Each particle uses its \"particleId\" value to choose its image\n"; break; case 2: $summary += " Each particle chooses a random image\n"; break; case 3: $summary += " Each particle uses its \"spriteNumPP\" value to choose its image\n"; break; case 4: if( $invert == 0 ) { $summary += " Each particle uses the ramp to choose its image\n"; } else { $summary += " Each particle uses the inverse of the ramp to choose its image\n"; } break; } } else { string $up = "up"; string $down = "down"; $summary += "Cycle Images:\n"; switch( $selection ) { case 0: $summary += " All particles use the first image in the sequence as their first image.\n"; break; case 1: $summary += " Each particle uses its \"particleId\" value to choose its first image.\n"; break; case 2: $summary += " Each particle chooses a random first image.\n"; break; case 3: $summary += " Each particle uses its \"spriteNumPP\" value to choose its first image.\n"; break; case 4: $summary += " Each particle uses the ramp connected to \"spriteNumRamp\" to choose its images.\n"; break; } if( $invert == 1 ) { $up = "down"; $down = "up"; } switch( $cycle ) { case 0: $summary += " The images will cycle "+$up+" linearly "; break; case 1: $summary += " The images will ease-in/ease-out "+$up+" "; break; case 2: $summary += " The images will cycle "+$up+" and then "+$down+" linearly "; break; case 3: $summary += " The images will ease-in/ease-out "+$up+" and then "+$down+" "; case 4: $summary += " The images will animated based on the \"spriteNumPP\" value"; case 5: $summary += " A ramp will control the image cycling "; break; } if( $cycleLength == 0 ) { $summary += "once over the lifespan."; } else { $summary += "every "+$cycleLength+" frames."; } } scrollField -e -text $summary swSummaryField; // // Display the summary frame. // textField -e -text "summary" swGlobalCurrentFrame; tabLayout -edit -selectTab swSummaryLayout WizardExampleWindowTabs; button -e -label "Apply" applyContinueButton; button -e -enable true backButton; } global proc swApplyContinueCallback() // // Description: // This is the callback for when the the "apply"/"continue" button // in the sprite wizard is pushed. { string $currentFrame = `textField -q -text swGlobalCurrentFrame`; if ( $currentFrame == "file" ) { int $frameRange = swFrameRange(); if ($frameRange == 0) { wizardExampleWindowSelectSummary(); } else { wizardExampleWindowSelectAnimation(); } } else if ( $currentFrame == "animation" ) { if (`radioButton -q -sl swSameSetupButton`) { doApplySprites(); } else { wizardExampleWindowSelectImageSelection(); } } else if ( $currentFrame == "imageSelection" ) { if (`radioButton -q -sl swCycleButton`) { wizardExampleWindowSelectCycle(); } else { wizardExampleWindowSelectSummary(); } } else if ( $currentFrame == "cycle" ) { wizardExampleWindowSelectSummary(); } else if ( $currentFrame == "summary" ) { doApplySprites(); } } global proc swBackCallback() // // Description: // This is the callback for the "back" button in the sprite wizard. { string $currentFrame = `textField -q -text swGlobalCurrentFrame`; if( $currentFrame == "file" ) { // // This should never happen, but if it does, // reset the animation frame. // wizardExampleWindowSelectFileSelection(); } else if( $currentFrame == "animation" ) { wizardExampleWindowSelectFileSelection(); } else if( $currentFrame == "imageSelection" ) { wizardExampleWindowSelectAnimation(); } else if( $currentFrame == "cycle" ) { wizardExampleWindowSelectImageSelection(); } else if( $currentFrame == "summary" ) { int $frameRange = swFrameRange(); if (0 == $frameRange) { wizardExampleWindowSelectFileSelection(); } else { if (`radioButton -q -sl swCycleButton`) { wizardExampleWindowSelectCycle(); } else { wizardExampleWindowSelectImageSelection(); } } } } global proc swCloseCallback() // // Description: // This is the callback for the "close" button in the sprite wizard. { deleteUI -window WizardExampleWindow; if (`window -exists WizardHelpWindow`) { deleteUI -window WizardHelpWindow; } } global proc resetSpriteSettings() // // Description: // This is the callback for the "reset settings" button. // Resets settings depending on the screen the user is on. // { string $currentFrame = `textField -q -text swGlobalCurrentFrame`; if ($currentFrame == "file") { textFieldButtonGrp -e -fileName "" swFileSelectionGroup; updateSelectedFileInfo(); } else if ($currentFrame == "animation") { radioButton -e -sl swSingleImageButton; } else if ($currentFrame == "imageSelection") { radioButton -e -sl swFirstImageButton; checkBox -e -enable false swInvertRampCheckbox; checkBox -e -value false swInvertRampCheckbox; } else if( $currentFrame == "cycle" ) { radioButton -e -sl swLinearUpButton; checkBox -e -value true swCycleOnceCheckBox; floatSliderGrp -e -value 100.0c swCycleLengthValue; floatSliderGrp -e -enable false swCycleLengthValue; checkBox -e -value false swInvertCycleCheckBox; } } global proc swMoreHelpCallback() // // Description: // This is the callback for the "help" button. Display help appropriate // to the screen the user is on. { string $currentFrame = `textField -q -text swGlobalCurrentFrame`; string $result; if ($currentFrame == "file") { wizardHelpWindow("Sprite File Selection:", {"Use the Browse button to select an image file. To use a sequence of image files, the image", "file name should be of the form name.number.fmt, for example: myImage.0007.iff. Any image", "in the sequence will do. Maya will be able to find the range of sequential images using", "the file names."}); } else if ($currentFrame == "animation") { wizardHelpWindow("Sprite Animation:", {"Choose whether as the animation plays, the sprites display a fixed image or a sequence", "of images."}); } else if ($currentFrame == "imageSelection") { wizardHelpWindow("Sprite Images:", {"Choose which image is used for each particle."}); } else if( $currentFrame == "cycle" ) { wizardHelpWindow("Sprite Cycling:", {"Choose how each sprite cycles the images."}); } else if( $currentFrame == "summary" ) { wizardHelpWindow("Summary Help:", {"The sprite wizard summary window shows you the options you have selected for your sprite.", "If you are happy with the options listed, click `Apply`. If you want to modify", "the options, click `Back` to edit the desired options."}); } } global proc updateAnimationApplyButton() { int $sameSetup = `radioButton -q -select swSameSetupButton`; if( $sameSetup == 1 ) { button -e -label "Apply" applyContinueButton; } else { button -e -label "Continue" applyContinueButton; } } proc createGlobalsFrame(string $parent) // // This frame is used strictly to hold global // variable values. It is never actually displayed. // { setParent $parent; columnLayout swGlobalsLayout; textField -text $parent -editable false swGlobalParent; textField -text "" -editable false swGlobalImageName; textField -text "" -editable false swGlobalParticleShape; intField -value 0 -editable false swGlobalSingleFrame; intField -value 0 -editable false swGlobalStartFrame; intField -value 0 -editable false swGlobalEndFrame; textField -text "" -editable false swGlobalCurrentFrame; } global proc getSpriteBaseFile() { string $dirMask = `workspace -q -rd`; string $sourceImg = `workspace -rte sourceImages`; if (size($sourceImg) > 0) { $dirMask += $sourceImg; } else { $sourceImg = `workspace -fre sourceImages`; if (size($sourceImg) > 0) { $dirMask += $sourceImg; } else if (`file -q -ex ($dirMask+"sourceimages")`) { $dirMask += "sourceImages"; } } $dirMask += ("/*"); string $spriteFile = `fileDialog -dm $dirMask`; textFieldButtonGrp -e -fileName $spriteFile swFileSelectionGroup; updateSelectedFileInfo(); } global proc updateSelectedFileInfo() { string $selectedFile = `textFieldButtonGrp -q -fileName swFileSelectionGroup`; int $badFileName = 0; if( ( $selectedFile == "" ) || ( `filetest -r $selectedFile` == 0 ) ) { if( `button -exists applyContinueButton` ) { button -e -enable false applyContinueButton; } if( $selectedFile != "" ) { $badFileName = 1; } $selectedFile = ""; } else { if( `button -exists applyContinueButton` ) { button -e -enable true applyContinueButton; } } string $fileInfo[]; if ($selectedFile != "") { $fileInfo = getConnectedFrameRange( $selectedFile ); } string $parent = `textField -q -text swGlobalParent`; string $range = ($parent+"|swFileSelectionLayout|swFileRangeLayout|swFileRangeInt|"); int $currentMin1 = `intField -q -min ($range+"field1")`; int $currentMin2 = `intField -q -min ($range+"field2")`; intFieldGrp -e -value1 (max(0,$currentMin1)) swFileRangeInt; intFieldGrp -e -value2 (max(0,$currentMin2)) swFileRangeInt; intField -e -min 0 ($range+"field1"); intField -e -min 0 ($range+"field2"); intField -e -max 99999 ($range+"field1"); intField -e -max 99999 ($range+"field2"); intFieldGrp -e -value1 0 swFileRangeInt; intFieldGrp -e -value2 0 swFileRangeInt; int $infoSize = size( $fileInfo ); if( $infoSize == 0 ) { // // There is no selected file. Go to the defaults. // textFieldGrp -e -text "" swSelectedFileText; intFieldGrp -e -enable false swFileRangeInt; columnLayout -e -visible false swFileRangeLayout; intField -e -value 1 swGlobalSingleFrame; } else if( $infoSize == 2 ) { // // The selected file was not numbered. // This is not an error. // textFieldGrp -e -text $fileInfo[1] swSelectedFileText; intFieldGrp -e -enable false swFileRangeInt; columnLayout -e -visible false swFileRangeLayout; intField -e -value 1 swGlobalSingleFrame; } else if( $infoSize == 4 ) { // // The file is numbered. // textFieldGrp -e -text $fileInfo[1] swSelectedFileText; int $firstFile = $fileInfo[2]; int $lastFile = $fileInfo[3]; intFieldGrp -e -value1 $firstFile swFileRangeInt; intFieldGrp -e -value2 $lastFile swFileRangeInt; intField -e -step 1 ($range+"field1"); intField -e -step 1 ($range+"field2"); intField -e -min $firstFile ($range+"field1"); intField -e -min $firstFile ($range+"field2"); intField -e -max $lastFile ($range+"field1"); intField -e -max $lastFile ($range+"field2"); intFieldGrp -e -enable true swFileRangeInt; intFieldGrp -e -label ("Min: "+$firstFile) swFileRangeInt; intFieldGrp -e -annotation "Index of first and last file to use." -extraLabel ($lastFile+" :Max") swFileRangeInt; columnLayout -e -visible true swFileRangeLayout; intField -e -value 0 swGlobalSingleFrame; } if( $badFileName == 1) { textFieldGrp -e -text "Bad File Name!" swSelectedFileText; } else { int $newFileName = newImageFileName($selectedFile); if (`radioButton -ex swSameSetupButton`) { radioButton -e -enable $newFileName swSameSetupButton; } } } proc createFileSelectionFrame(string $parent) { setParent $parent; columnLayout swFileSelectionLayout; text -label "Image File Selection:"; text -label "Click on the \"Browse\" button to select the image sequence."; textFieldButtonGrp -label "Sprite File" -annotation "Specify the file name of one of the images in the sequence." -text "" -buttonLabel "Browse" -buttonCommand "getSpriteBaseFile()" -changeCommand "updateSelectedFileInfo()" swFileSelectionGroup; textFieldGrp -label "Base Name" -text "" -annotation "This field will be filled automatically when a sprite file is specified." -editable false swSelectedFileText; columnLayout -visible false swFileRangeLayout; text -label ""; text -label "Choose files within available continuous range that contains the selected file."; intFieldGrp -label "Min" -extraLabel "Max" -numberOfFields 2 -value1 0 -value2 0 -enable false swFileRangeInt; updateSelectedFileInfo(); } proc createAnimationFrame(string $parent) // // Description: // Create the Frame 1 UI. // // Arguments: // The parent argument is assumed to be a tabLayout. // { setParent $parent; columnLayout swAnimationOptionsLayout; text -label "Image Assignment:"; radioCollection swAnimationOptionCollection; radioButton -label "No animation. Use a single image for each particle." -ann "Each particle uses some fixed image throughout its lifetime" -sl -align "left" swSingleImageButton; radioButton -label "Cycle through the images for each particle." -ann "Each particle displays a sequence of images in turn" -align "left" swCycleButton; string $selectedFile = `textFieldButtonGrp -q -fileName swFileSelectionGroup`; int $newFileName = newImageFileName($selectedFile); radioButton -label "Use existing setup with new images." -ann "Use the new image sequence just picked and leave all other options unchanged. This option is only valid when editing existing particle sprites." -align "left" -cc "updateAnimationApplyButton()" -enable $newFileName swSameSetupButton; } global proc updateInvertRampCheckbox() { int $useRamp = `radioButton -q -select swRampButton`; checkBox -e -enable $useRamp swInvertRampCheckbox; } proc createImageSelectionFrame(string $parent) // // Description: // Create the Frame 2 UI. // // Arguments: // The parent argument is assumed to be a tabLayout. // { setParent $parent; columnLayout swImageSelectionLayout; text -label "Initial Sprite Assignment:"; text -label "Select the technique used to assign the initial sprite to each particle:"; radioCollection swImageSelectionOptionCollection; radioButton -label "Use the first image in the sequence" -ann "Every particle will use the first image in the sequence." -sl -align "left" swFirstImageButton; radioButton -label "Use each particle's \"particleId\" value" -ann "The particle will use its \"particleId\" to pick an image. If a particleId is greater than the number of images in the sequence, start over with the first." -align "left" swParticleIdButton; radioButton -label "Random" -ann "Each particle will choose a random image from the sequence." -align "left" swRandomButton; radioButton -label "Custom Start" -ann "The particle will use its \"spriteNumPP\" to pick an image. It is the user's responsibility to set the spriteNumPP values by editing the particle creation expression." -align "left" swSpriteNumPPButton; radioButton -label "Use a ramp" -ann "A ramp will be connected to the \"spriteNumRamp\" attribute on the particle object. This ramp can be modified to determine which sprite receives each image." -align "left" swInitRampButton; } global proc updateCycleLength() { int $cycleOnce = `checkBox -q -value swCycleOnceCheckbox`; floatSliderGrp -e -enable (!$cycleOnce) swCycleLengthValue; } proc createCycleOptionsFrame(string $parent) // // Description: // Create the Frame 3 UI. // // Arguments: // The parent argument is assumed to be a tabLayout. // { setParent $parent; columnLayout swCycleOptionsLayout; text -label "Animation Assignment:"; text -label "How do you want the images to be cycled for each particle?"; radioCollection swCycleOptionCollection; radioButton -label "Linearly Increasing" -ann "Play through the image sequence at an even speed." -sl -align "left" swLinearUpButton; radioButton -label "Ease-In/Ease-Out Increasing" -ann "Ease-in and ease-out the rate that the image sequence is played. The first and last images in the sequence will be used for longer times." -align "left" swSmoothUpButton; radioButton -label "Linearly Increasing And Decreasing" -ann "Play through image sequence at an even speed. When the end of the sequence is reached, play it in reverse." -align "left" swLinearUpDownButton; radioButton -label "Ease-In/Ease-Out Increasing And Decreasing" -ann "Ease-in and ease-out the rate that the image sequence is played. When the end of the sequence is reached, play it in reverse." -align "left" swSmoothUpDownButton; radioButton -label "Use a ramp" -ann "A ramp will be connected to the \"spriteNumRamp\" attribute on the particle object. This ramp can be modified to determine which sprite receives each image." -align "left" -cc "updateInvertRampCheckbox()" swRampButton; checkBox -label "Invert Ramp" -align "left" -value false -enable false -ann "Invert the meaning of the ramp's values. Higher values mean use images closer to the start of the sequence." swInvertRampCheckbox; radioButton -label "Custom Cycling" -ann "The particle will use its \"spriteNumPP\" to pick an image. It is the user's responsibility to set the spriteNumPP values by editing the particle runtime expression." -align "left" swSpriteCustomButton; separator -w 200 -h 5 -style "in"; checkBox -label "Cycle only once during lifespan" -ann "The animation will be timed to cycle once during the particle lifespan." -align "left" -value true -changeCommand "updateCycleLength()" swCycleOnceCheckbox; floatSliderGrp -label "Cycle Length In Frames" -ann "This option is only valid if the \"Cycle only once during lifespan\" checkbox is disabled. It conrols the length of each animation cycle." -field true -min 1 -precision 1 -step 1.0 -value 100.0 -enable false swCycleLengthValue; checkBox -label "Invert Cycle" -align "left" -value false swInvertCycleCheckbox; } proc createSummaryFrame(string $parent) // // Description: // Create the Frame 3 UI. // // Arguments: // The parent argument is assumed to be a tabLayout. // { setParent $parent; columnLayout swSummaryLayout; text -label "Summary"; scrollField -width 442 -height 150 -editable false -font "smallPlainLabelFont" -text "This is a summary of the sprite options." swSummaryField; } proc createTabs(string $parent) // // Description: // // Arguments: // The parent argument is assumed to be a tabLayout. // { createGlobalsFrame($parent); createFileSelectionFrame($parent); createAnimationFrame($parent); createImageSelectionFrame($parent); createCycleOptionsFrame($parent); createSummaryFrame($parent); } proc createButtons(string $parent) // // Description: // Create buttons (one for each frame) that also switch between // the tabs. // // Arguments: // The parent argument is assumed to be a formLayout. // { setParent $parent; string $frame1 = `button -label "Continue" -ann "Make this choice, and go on to the next screen" -command "swApplyContinueCallback" applyContinueButton`; string $frame2 = `button -label "Back" -enable false -ann "Return to the previous screen" -command "swBackCallback" backButton`; // string $frame3 = `button -label "More Help" // -ann "Explain some more about this topic" // -command "swMoreHelpCallback" // moreHelpButton`; string $frame4 = `button -label "Close" -ann "Quit the wizard and close the window" -command "swCloseCallback" closeButton`; formLayout -edit -attachForm $frame1 "top" 5 -attachForm $frame1 "left" 5 -attachForm $frame1 "bottom" 5 -attachPosition $frame1 "right" 2 33 -attachForm $frame2 "top" 5 -attachPosition $frame2 "left" 2 33 -attachPosition $frame2 "right" 2 66 -attachForm $frame2 "bottom" 5 // -attachForm $frame3 "top" 5 // -attachPosition $frame3 "left" 2 50 // -attachPosition $frame3 "right" 2 75 // -attachForm $frame3 "bottom" 5 -attachForm $frame4 "top" 5 -attachPosition $frame4 "left" 2 66 -attachForm $frame4 "bottom" 5 -attachForm $frame4 "right" 5 $parent; } global proc wizardWindow( string $particle, string $newImage ) // // Description: // { global string $gSpriteWizardParticle; $gSpriteWizardParticle = $particle; // If the window already exists then just show it and return. // if (`window -exists SpriteWizardWindow`) { deleteUI -window SpriteWizardWindow; } // Otherwise, build the window. // window -title ("Sprite Wizard: "+$particle) -iconName "Sprite Wizard" -width 475 -height 300 -sizeable true WizardExampleWindow; string $menuBarLayout = `menuBarLayout`; menu -label "Edit"; menuItem -label "Reset Settings" -c "resetSpriteSettings"; menu -label "Help" -helpMenu true; menuItem -label "Help on the Sprite Wizard..." -c "showHelp SpriteWizard"; setParent ..; string $form = `formLayout SpriteWizardForm`; string $tabs = `tabLayout -tabsVisible true -innerMarginWidth 5 -innerMarginHeight 5 WizardExampleWindowTabs`; setParent ..; string $buttons = `formLayout`; setParent ..; createTabs($tabs); createButtons($buttons); wizardExampleWindowSelectFileSelection(); tabLayout -edit -tabLabelIndex 1 "Globals" -tabLabelIndex 2 "Sprite File Selection" -tabLabelIndex 3 "Sprite Animation Options" -tabLabelIndex 4 "Image Selection Options" -tabLabelIndex 5 "Cycle Options" -tabLabelIndex 6 "Summary" $tabs; formLayout -edit -attachForm $tabs "top" 0 -attachForm $tabs "left" 0 -attachControl $tabs "bottom" 0 $buttons -attachForm $tabs "right" 0 -attachNone $buttons "top" -attachForm $buttons "left" 0 -attachForm $buttons "bottom" 0 -attachForm $buttons "right" 0 $form; tabLayout -e -tabsVisible 0 WizardExampleWindowTabs; initializeWizardFromParticleShape( $particle, $newImage ); showWindow WizardExampleWindow; } global proc initializeWizardFromParticleShape( string $particle, string $newImage ) { if( $particle != "" ) { string $particleChildren[] = `ls -dag -type particle $particle`; if( size( $particleChildren ) == 0 ) { $particle = ""; } else if( size( $particleChildren ) > 1 ) { error("There are "+(size($particleChildren))+" particle objects at or below \""+$particle+"\" in the scene. Select exactly one."); } else { $particle = $particleChildren[0]; } } if( $particle == "" ) { error("No particle object selected. Select exactly one."); } textField -e -text $particle swGlobalParticleShape; if( $newImage == "" ) { string $fileTexture = particleSpriteFileTexture( $particle ); if( $fileTexture != "" ) { string $file = `getAttr ($fileTexture+".fileTextureName")`; string $fileInfo[] = getConnectedFrameRange( $file ); if( size( $fileInfo ) == 0 ) { $file = ""; } textFieldButtonGrp -e -fileName $file swFileSelectionGroup; updateSelectedFileInfo(); if( size( $fileInfo ) == 4 ) { int $startFrame = `getAttr ($fileTexture+".startCycleExtension")`; int $endFrame = `getAttr ($fileTexture+".endCycleExtension")`; intFieldGrp -e -value1 $startFrame swFileRangeInt; intFieldGrp -e -value2 $endFrame swFileRangeInt; } } } else { textFieldButtonGrp -e -fileName $newImage swFileSelectionGroup; updateSelectedFileInfo(); } // // Animation // if( `attributeQuery -exists -node $particle SpriteAnimation` ) { int $animation = `getAttr ($particle+".SpriteAnimation")`; switch( $animation ) { case 0: radioButton -e -select swSingleImageButton; break; case 1: radioButton -e -select swCycleButton; break; } } else { radioButton -e -select swSingleImageButton; } // // Image Selection // if( `attributeQuery -exists -node $particle SpriteStartOption` ) { int $start = `getAttr ($particle+".SpriteStartOption")`; switch( $start ) { case 0: radioButton -e -select swFirstImageButton; break; case 1: radioButton -e -select swParticleIdButton; break; case 2: radioButton -e -select swRandomButton; break; case 3: radioButton -e -select swSpriteNumPPButton; break; case 4: radioButton -e -select swInitRampButton; break; } } else { radioButton -e -select swFirstImageButton; } updateInvertRampCheckbox(); // // Cycle Pattern // if( `attributeQuery -exists -node $particle SpriteCyclePattern` ) { int $cycle = `getAttr ($particle+".SpriteCyclePattern")`; switch( $cycle ) { case 0: radioButton -e -select swLinearUpButton; break; case 1: radioButton -e -select swSmoothUpButton; break; case 2: radioButton -e -select swLinearUpDownButton; break; case 3: radioButton -e -select swSmoothUpDownButton; break; case 4: radioButton -e -select swSpriteCustomButton; break; case 5: radioButton -e -select swRampButton; break; } } else { radioButton -e -select swLinearUpButton; } // // Cycle Length // if( `attributeQuery -exists -node $particle SpriteCycleLength` ) { float $cycleLength = `getAttr ($particle+".SpriteCycleLength")`; floatSliderGrp -e -value $cycleLength swCycleLengthValue; if( $cycleLength == 0 ) { checkBox -e -value 1 swCycleOnceCheckbox; floatSliderGrp -e -value 100.0 swCycleLengthValue; } else { checkBox -e -value 0 swCycleOnceCheckbox; } } else { checkBox -e -value 1 swCycleOnceCheckbox; floatSliderGrp -e -value 100.0 swCycleLengthValue; } updateCycleLength(); // // Invert // if( `attributeQuery -exists -node $particle SpriteInvertCycle` ) { int $invert = `getAttr ($particle+".SpriteInvertCycle")`; checkBox -e -value $invert swInvertRampCheckbox; checkBox -e -value $invert swInvertCycleCheckbox; } else { checkBox -e -value 0 swInvertRampCheckbox; checkBox -e -value 0 swInvertCycleCheckbox; } } global proc string particleSpriteFileTexture( string $particle ) { string $result = ""; if( size( `ls -type particle $particle` ) == 1 ) { if( `getAttr ($particle+".particleRenderType")` == 5 ) { string $shadingGroups[] = `listConnections -source false -destination true -plugs false ($particle+".instObjGroups")`; int $i; for( $i = 0; $i < size( $shadingGroups ); $i ++ ) { string $shaders[] = `listConnections -source true -destination false -plugs false ($shadingGroups[$i]+".surfaceShader")`; $shaders = `ls -type lambert $shaders`; int $j; for( $j = 0; $j < size( $shaders ); $j ++ ) { string $drivingColor[] = `listConnections -plugs false -source true -destination false ($shaders[$j]+".color")`; if( size( $drivingColor ) > 0 ) { string $fileTx[] = `ls -type file $drivingColor[0]`; if( size( $fileTx ) > 0 ) { $result = $fileTx[0]; return $result; } } } } } } return $result; } global proc string[] getConnectedFrameRange( string $fileName ) { string $result[]; clear( $result ); // // First, make sure that the given string. // is a readable file. // if( `filetest -r $fileName` == 0 ) { print("// Error: Cannot read file: "+$fileName+"\n"); return $result; } // // Now get the path to the file. // string $path[]; clear( $path ); tokenize( $fileName, "/", $path ); int $pathCount = size( $path ); string $pathDir = ""; if( substring( $fileName, 1, 1 ) == "/" ) { $pathDir = "/"; } string $fileBase = $path[$pathCount-1]; int $j; for( $j = 0; $j < ( $pathCount - 1 ); $j ++ ) { $pathDir = ( $pathDir + $path[$j] + "/" ); } // // Now try to find which part of the file's name contains // the extensions. // string $parts[]; clear( $parts ); tokenize( $fileBase, ".", $parts ); int $partCount = size( $parts ); int $numberPart[]; int $isFileNumbered = 0; int $extension = 0; for( $j = 0; $j < $partCount; $j ++ ) { if( `gmatch $parts[$j] "[0-9]*"` == 1 ) { $numberPart[$j] = 1; $isFileNumbered = 1; $extension = $j; } else { $numberPart[$j] = 0; } } if( $isFileNumbered == 0 ) { clear( $result ); $result[0] = $pathDir; $result[1] = $fileBase; return $result; } int $selectedImageNumber = $parts[$extension]; int $fileIsPadded = 0; if( size( $parts[$extension] ) > 1 ) { if( substring( $parts[$extension], 1, 1 ) == "0" ) { // // Since the numbering is more than 1 character long, // and the first character is "0", we assume that // the file numbering is using padding. // $fileIsPadded = 1; } } string $format = ""; for( $j = 0; $j < $partCount; $j ++ ) { if( $j == $extension ) { if( $fileIsPadded == 1 ) { $format += "????"; } else { $format += "*"; } } else { $format += $parts[$j]; } if( $j < ( $partCount - 1 ) ) { $format += "."; } } string $candidateFiles[]; clear( $candidateFiles ); if( $pathDir != "" ) { $candidateFiles = `getFileList -folder $pathDir -filespec $format`; } else { $candidateFiles = `getFileList -filespec $format`; } int $fileCount = size( $candidateFiles ); if( $fileCount == 1 ) { clear( $result ); if( $fileBase == $candidateFiles[0] ) { $result[0] = $pathDir; $result[1] = $fileBase; } else { // // If the one matching file is not the // selected file, then something is // really messed up. // } return $result; } // // Loop over all of the files that match the format to // find ones that are within the continuous range that // includes the selected file. // int $numbers[]; clear( $numbers ); for( $j = 0; $j < size( $candidateFiles ); $j ++ ) { string $candidateParts[]; tokenize( $candidateFiles[$j], ".", $candidateParts ); string $ext = $candidateParts[$extension]; int $padded = 0; if( size( $ext ) > 1 ) { if( substring( $ext, 1, 1 ) == "0" ) { $padded = 1; } } // // Only keep the files that seem to match the // format. // if( $fileIsPadded == $padded ) { $numbers[size( $numbers )] = $ext; } } $numbers = sort( $numbers ); int $selectedLocation = -1; for( $j = 0; $j < size( $numbers ); $j ++ ) { if( $numbers[$j] == $selectedImageNumber ) { $selectedLocation = $j; break; } } if( $selectedLocation == -1 ) { // // The selected file was not in the matching list. // That means that something got really messed up. // clear( $result ); return $result; } // // Starting at the location of the selected image, work // up and down the $numbers array to find the maximum range // of continuous numbers. // int $minimumIndex = -1; if( $selectedLocation == 0 ) { $minimumIndex = 0; } int $maximumIndex = -1; if( $selectedLocation == ( size( $numbers ) - 1 ) ) { $maximumIndex = $selectedLocation; } if( $minimumIndex == -1 ) { int $lastValue = $numbers[$selectedLocation]; for( $j = $selectedLocation - 1; $j >= 0; $j -- ) { if( ( $lastValue - $numbers[$j] ) > 1 ) { break; } $lastValue = $numbers[$j]; $minimumIndex = $j; } } if( $minimumIndex == -1 ) { $minimumIndex = $selectedLocation; } if( $maximumIndex == -1 ) { int $lastValue = $numbers[$selectedLocation]; for( $j = $selectedLocation + 1; $j < size( $numbers ); $j ++ ) { if( ( $numbers[$j] - $lastValue ) > 1 ) { break; } $lastValue = $numbers[$j]; $maximumIndex = $j; } } if( $maximumIndex == -1 ) { $maximumIndex = $selectedLocation; } $result[0] = $pathDir; $result[1] = $fileBase; if( $numbers[$maximumIndex] != $numbers[$minimumIndex] ) { $result[2] = $numbers[$minimumIndex]; $result[3] = $numbers[$maximumIndex]; } return $result; }